/**
 * 权限声明：
 * 源码可自由修改。
 */
package com.handy.webwork.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.handy.webwork.action.ActionMapping;
import com.handy.webwork.action.ActionResult;
import com.handy.webwork.plugin.PluginBean;

/**
 * 配置文件存储类,单例模式,使用时不要使用new HandyConfiguration(),<br>
 * 要调用HandyConfiguration.getInstance()生成实例。<br>
 * 
 * 框架启动后,由ConfigurationManager读取配置文件,将配置文件存储到内存中,方便调用.
 * 
 * @author rocken.zeng@gmail.com
 * 
 */
public class HandyConfiguration {

	private HandyConfiguration(){}
	/**
	 * 获取实例.
	 * 
	 * @return
	 */
	public static synchronized HandyConfiguration getInstance() {
		if (instance == null) {
			instance = new HandyConfiguration();
		}
		return instance;
	}

	/**
	 * 指定key,读取handy.properties中相应的value.
	 * 
	 * @param key
	 * @return
	 */
	public static String properties(String key) {
		return getInstance().properties.get(key);
	}

	public static void putProperties(String key, String value) {
		getInstance().properties.put(key, value);
	}

	public static void putScriptFiles(List<String> files){
		getInstance().scriptFiles.addAll(files);
	}
	
	/**
	 * 项目下所有xml与properties文件列表。
	 * @return
	 */
	public static Set<String> scriptFiles(){
		return getInstance().scriptFiles;
	}
	/**
	 * 返回所有插件.
	 * 
	 * @return
	 */
	public static ArrayList<PluginBean> Plugins() {
		return getInstance().plugins;
	}

	public static void putPlugins(PluginBean plugin) {
		getInstance().plugins.add(plugin);
	}

	@SuppressWarnings("unchecked")
	public static void putAllPlugins(List<PluginBean> _plugins) {
		if (_plugins != null) {
			getInstance().plugins.addAll(_plugins);
		}
	}

	/**
	 * 指定key,读取freemarker.properties中相应的value.
	 * 
	 * @param key
	 * @return
	 */
	public static String freemarkers(String key) {
		return getInstance().freemarkers.get(key);
	}

	public static void putFreemarkers(String key, String value) {
		getInstance().freemarkers.put(key, value);
	}

	/**
	 * 查找指定uri的action mapping,uri对应的是action mapping name.
	 * 
	 * @param uri
	 * @return
	 */
	public static ActionMapping actionMappings(String uri) {
		return getInstance().actionMappings.get(uri);
	}

	public static void putActionMappings(String key, ActionMapping value) {
		getInstance().actionMappings.put(key, value);
	}

	/**
	 * 查找指定包名的interceptor
	 * 
	 * @param key
	 * @return
	 */
	public static LinkedList<ActionMapping> interceptorMappings(String key) {
		return getInstance().interceptorMappings.get(key);
	}

	public static void putInterceptorMappings(String key,
			LinkedList<ActionMapping> value) {
		getInstance().interceptorMappings.put(key, value);
	}

	public static void putRootPath(String rootPath) {
		getInstance().rootPath = rootPath;
	}

	/**
	 * 站点根路径.
	 * 
	 * @return
	 */
	public static String rootPath() {
		return getInstance().rootPath;
	}

	/**
	 * 框架是否自动处理页面参数.
	 * 
	 * @return
	 */
	public static boolean autoHandleParam() {
		boolean auto = false;
		// 是否自动处理form参数
		String autoHandleForm = properties(PROP_AUTODEALWITHFORM);
		if (null != autoHandleForm && autoHandleForm.equalsIgnoreCase("true")) {
			auto = true;
		} else {
			auto = false;
		}
		return auto;
	}

	/**
	 * 清空hashmap
	 */
	public void clear() {
		if (properties != null)
			properties.clear();
		if (plugins != null)
			plugins.clear();
		if (actionMappings != null)
			actionMappings.clear();
		if (interceptorMappings != null)
			interceptorMappings.clear();
		if (freemarkers != null)
			freemarkers.clear();
	}

	private static Log log = LogFactory.getLog(HandyConfiguration.class);
	private static HandyConfiguration instance = null;

	/**
	 * 站点根路径.
	 */
	private String rootPath = "";

	/**
	 * 系统行为控制参数。
	 */
	private HashMap<String, String> properties = new HashMap<String, String>();

	/**
	 * 插件集合。
	 */
	private ArrayList<PluginBean> plugins = new ArrayList<PluginBean>();

	/**
	 * 控制器地址映射表。 key:控制器名称 value:控制器
	 * 
	 * 项目初始化时将配置文件里所有控制器读入该Map， 当用户访问时，通过URI在actionMappings时找到相应控制器。
	 */
	private HashMap<String, ActionMapping> actionMappings = new HashMap<String, ActionMapping>();

	/**
	 * 包中定义的拦截器链表。 key:包名 value:拦截器链表
	 * 
	 * 项目初始化时将配置文件里所有拦截器读入该Map，
	 * 当用户访问时，通过URI在actionMappings时找到相应控制器，执行该控制器所属包的所有拦截器。
	 */
	private HashMap<String, LinkedList<ActionMapping>> interceptorMappings = new HashMap<String, LinkedList<ActionMapping>>();

	/**
	 * freemarker设置属性。
	 */
	private HashMap<String, String> freemarkers = new HashMap<String, String>();
	
	/**
	 * 项目下所有脚本文件列表。
	 */
	private Set<String> scriptFiles = new HashSet<String>();

	/* constants *********************************************** */

	/**
	 * 对应handy.properties中的autoDealWithForm.
	 */
	public final static String PROP_AUTODEALWITHFORM = "AUTODEALWITHFORM";

	/**
	 * 对应handy.properties中的suffix.
	 */
	public final static String PROP_SUFFIX = "SUFFIX";

	/**
	 * 对应handy.properties中的uploadFileMaxRequestSize.
	 */
	public final static String PROP_UPLOADFILEMAXREQUESTSIZE = "UPLOADFILEMAXREQUESTSIZE";

	/**
	 * 对应handy.properties中的uploadFileMaxMemorySize.
	 */
	public final static String PROP_UPLOADFILEMAXMEMORYSIZE = "UPLOADFILEMAXMEMORYSIZE";

	/**
	 * 对应handy.properties中的uploadFileTempDirectory.
	 */
	public final static String PROP_UPLOADFILETEMPDIRECTORY = "UPLOADFILETEMPDIRECTORY";

	/**
	 * 对应handy.properties中的messageRessource.
	 */
	public final static String PROP_MESSAGERESSOURCE = "MESSAGERESSOURCE";

	/**
	 * 对应handy.properties中的encoding.
	 */
	public final static String PROP_ENCODING = "ENCODING";

	/**
	 * 对应handy.properties中的datasource.
	 */
	public final static String PROP_DATASOURCE = "DATASOURCE";

	/**
	 * 对应freemarker.properties中的number_format.
	 */
	public final static String FREEMARKER_NUMBER_FORMAT = "NUMBER_FORMAT";

	/**
	 * 对应freemarker.properties中的cache.
	 */
	public final static String FREEMARKER_CACHE = "CACHE";

	/**
	 * 对应freemarker.properties中的locale.
	 */
	public final static String FREEMARKER_LOCALE = "LOCALE";

	/**
	 * 对应freemarker.properties中的date_format.
	 */
	public final static String FREEMARKER_DATE_FORMAT = "DATE_FORMAT";

	/**
	 * 对应freemarker.properties中的datetime_format.
	 */
	public final static String FREEMARKER_DATETIME_FORMAT = "DATETIME_FORMAT";

	/**
	 * 处理结果推送到freemarker result.
	 */
	public final static String RESULT_FREEMARKER = "FREEMARKER";

	/**
	 * 处理结果推送到forward result.
	 */
	public final static String RESULT_FORWARD = "FORWARD";

	/**
	 * 处理结果推送到redirect result.
	 */
	public final static String RESULT_REDIRECT = "REDIRECT";

	/**
	 * action.
	 */
	public final static int ACTION_SYTLE_ACTION = 0;

	/**
	 * interceptor.
	 */
	public final static int ACTION_SYTLE_INTERCEPTOR = 1;

	/**
	 * forward.
	 */
	public final static int ACTION_SYTLE_FORWARD = 2;

	/**
	 * 对应资源文件的uploadFileError字段
	 */
	public final static String ERROR_UPLOADFILE = "UPLOADFILEERROR";

	/** ********************************************* */
	/* 打印配置文件 */

	@SuppressWarnings("unchecked")
	public void printActionMappings() {
		Set<Entry<String, ActionMapping>> actionParams = actionMappings
				.entrySet();
		for (Map.Entry actionEntry : actionParams) {
			ActionMapping action = (ActionMapping) actionEntry.getValue();
			log.info("<action name=\"" + action.getActionName()
					+ "\" class=\"" + action.getActionClass() + "\">");
			HashMap<String, ActionResult> resultMap = action.getActionResults();
			Set<Entry<String, ActionResult>> resultParams = resultMap
					.entrySet();
			for (Map.Entry resultEntry : resultParams) {
				ActionResult result = (ActionResult) resultEntry.getValue();
				log.info("	<result name=\"" + result.getResultName()
						+ "\" type=\"" + result.getResultType() + "\" contentType=\""+ result.getContentType() +"\">"
						+ result.getResultValue() + "</result>");
			}
			log.info("</action>");
		}
	}

	@SuppressWarnings("unchecked")
	public void printInterceptorMappings() {

		Set<Entry<String, LinkedList<ActionMapping>>> params = interceptorMappings
				.entrySet();
		for (Map.Entry entry : params) {
			String _key = (String) entry.getKey();
			LinkedList<ActionMapping> _interceptors = (LinkedList<ActionMapping>) interceptorMappings
					.get(_key);

			for (ActionMapping interceptor : _interceptors) {
				log.info("<interceptor name=\"" + interceptor.getActionName()
						+ "\" class=\"" + interceptor.getActionClass() + "\">");
				HashMap<String, ActionResult> resultMap = interceptor
						.getActionResults();
				Set<Entry<String, ActionResult>> resultParams = resultMap
						.entrySet();
				for (Map.Entry<String, ActionResult> resultEntry : resultParams) {
					ActionResult result = (ActionResult) resultEntry.getValue();
					log.info(" <result name=\"" + result.getResultName()
							+ "\" type=\"" + result.getResultType() + "\" contentType=\""+ result.getContentType() +"\">"
							+ result.getResultValue() + "</result>");
				}
				log.info("</interceptor>");
			}
		}

	}

	@SuppressWarnings("unchecked")
	public void printProperties() {
		Set<Entry<String, String>> params = properties.entrySet();
		for (Map.Entry entry : params) {
			String _key = (String) entry.getKey();
			String _value = (String) entry.getValue();
			log.info(_key + " = " + _value);
		}
	}

	@SuppressWarnings("unchecked")
	public void printFreemarker() {
		Set<Entry<String, String>> params = freemarkers.entrySet();
		for (Map.Entry entry : params) {
			String _key = (String) entry.getKey();
			String _value = (String) entry.getValue();
			log.info(_key + " = " + _value);
		}
	}

	public void printPlugins() {
		for (PluginBean plugin : plugins) {
			log.info(plugin.toString());
		}
	}
}